/*******************************************************************************
  * 文件：ZCD.c
  * 作者：djy
  * 版本：v1.0.0
  * 日期：2021-05-11
  * 说明：过零检测（Zero Crossing Detection）相关
*******************************************************************************/
#include "ZCD.h"
#include "RelayCtrl.h"
#include "RelayPower.h"
#include "Hardware_IO.h"
#include "Hardware_Timer.h"

static Timer_ts sTimer;
static U8 u8SecondFlag = 0;     // 秒标志
static U8 u8FilterTimes = 0;    // 滤波次数
/*******************************************************************************
  * 函数名：ZeroCrossDisappearCallBack
  * 功  能：过零信号消失超时回调处理函数
  * 参  数：无
  * 返回值：无
  * 说  明：当过零信号消失60ms(三个过零信号周期)时间后，关闭全部负载继电器
*******************************************************************************/
static void ZeroCrossDisappearCallBack(void)
{
    // 关闭所有负载继电器标志位
    RelayCtrlReserve(OFF);
    RelayCtrlBackFan1(OFF);
    RelayCtrlBackFan2(OFF);
    RelayCtrlMotor(OFF);
    RelayCtrlCoolFan1(OFF);
    RelayCtrlCoolFan2(OFF);
    RelayCtrlSteamPanOut(OFF);
    RelayCtrlSteamPanIn(OFF);
    RelayCtrlUpInHeatTube(OFF);
    RelayCtrlUpOutHeatTube(OFF);
    RelayCtrlDownHeatTube(OFF);
    RelayCtrlLamp(OFF);
    RelayCtrlBackHeatTube(OFF);
    
    // 直接关闭负载控制IO
    Hardware_ReserveCtrl(OFF);
    Hardware_BackFan1Ctrl(OFF);
    Hardware_BackFan2Ctrl(OFF);
    Hardware_WaxMotorCtrl(OFF);
    Hardware_CoolFanACtrl(OFF);
    Hardware_CoolFanBCtrl(OFF);
    Hardware_SteamPanOutCtrl(OFF);
    Hardware_SteamPanInCtrl(OFF);
    Hardware_UpInHeatCtrl(OFF);
    Hardware_UpOutHeatCtrl(OFF);
    Hardware_DownHeatCtrl(OFF);
    Hardware_LampCtrl(OFF);
    Hardware_BackHeatCtrl(OFF);
    Hardware_OutletValveCtrl(OFF);
    Hardware_InletValveCtrl(OFF);
    Hardware_EffluentValveCtrl(OFF);
    Hardware_EffluentPumpCtrl(OFF);

    // 关闭零总
    RelayZeroLine1Ctrl(OFF);
    RelayZeroLine2Ctrl(OFF);

    // 关闭继电器12V供电
    Relay12VolCtrl(OFF);
}

/*******************************************************************************
  * 函数名：ZeroCrossDetectHandler
  * 功  能：过零检测处理函数
  * 参  数：无
  * 返回值：无
  * 说  明：1.过零检测无滤波时，引脚配置为上升沿中断,中断20ms触发一次，
  *         220ms回调一次继电器控制函数
  *        2.
*******************************************************************************/
void ZeroCrossDetectHandler(void)
{
    volatile static U16 u16Tick_220MS = 0;
    volatile static U16 u16Tick_1S = 0;

    // 时基累加
    u16Tick_220MS++;
    u16Tick_1S++;

    // 220ms时间到
    if(u16Tick_220MS >= 11)
    {
        // 时基清零
        u16Tick_220MS = 0;

        // 回调继电器控制函数
        RelayCtrlHook_220MS();
    }

    // 1S时间到
    if(u16Tick_1S >= 50)
    {
        // 时基清零
        u16Tick_1S = 0;

        // 取反秒标志
        u8SecondFlag = !u8SecondFlag;
    }

    // 重启超时定时器
    OS_TimerRestart(&sTimer,60,ZeroCrossDisappearCallBack);
}

/*******************************************************************************
  * 函数名：GetSecondFlag
  * 功  能：获取秒标志
  * 参  数：无
  * 返回值：无
  * 说  明：无
*******************************************************************************/
U8 GetSecondFlag(void)
{
    return u8SecondFlag;
}

/*******************************************************************************
  * 函数名：ZeroCrossExtIntHandler
  * 功  能：过零外部中断处理函数
  * 参  数：无
  * 返回值：无
  * 说  明：上升沿外部中断
*******************************************************************************/
void ZeroCrossExtIntHandler(void)
{
    // 停止定时器
    Hardware_StopZeroCrossTimer();
    // 清零滤波次数
    u8FilterTimes = 0;
    // 开启定时器，开始滤波
    Hardware_StartZeroCrossTimer();
}

/*******************************************************************************
  * 函数名：ZeroCrossTimerIntHandler
  * 功  能：过零定时器中断处理函数
  * 参  数：无
  * 返回值：无
  * 说  明：过零检测IO口高电平持续1MS，方可认为有效过零点；
*******************************************************************************/
void ZeroCrossTimerIntHandler(void)
{
    // 过零检测高电平
    if(Hardware_ZeroCrossPort())
    {
        // 更新滤波次数
        u8FilterTimes++;
        // 超过10次，即10x100us=1ms
        if(u8FilterTimes >= 10)
        {
            // 停止定时器
            Hardware_StopZeroCrossTimer();
            // 清零滤波次数
            u8FilterTimes = 0;
            // 回调过零处理函数
            ZeroCrossDetectHandler();
            // 恢复继电器12V供电
            Relay12VolCtrl(ON);
        }
    }
    // 过零检测低电平
    else
    {
        // 停止定时器
        Hardware_StopZeroCrossTimer();
        // 清零滤波次数
        u8FilterTimes = 0;
    }
}
